@file:OptIn(ExperimentalNativeApi::class, ExperimentalForeignApi::class)

package com.example.kotlin_library

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import coil3.ImageLoader
import coil3.*
import coil3.asImage
import coil3.compose.AsyncImage
import coil3.decode.DecodeResult
import coil3.decode.Decoder
import coil3.decode.ImageSource
import coil3.fetch.SourceFetchResult
import coil3.request.Options
import coil3.size.Size
import com.example.kotlin_library.native.*
import kotlinx.cinterop.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext
import androidx.compose.ui.graphics.toComposeImageBitmap
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import coil3.Canvas
import coil3.request.ErrorResult
import coil3.request.SuccessResult
import coil3.Image
import okio.BufferedSource
import okio.use
import org.jetbrains.skia.Image as SkiaImage
import kotlin.experimental.ExperimentalNativeApi
import coil3.compose.LocalPlatformContext
//import java.io.File

/**
 * OHOS 平台的 UniversalAsyncImage 实现
 *
 * 使用 Coil 3 的 AsyncImage，配合自定义的 OhosImageDecoder
 */

/**
 * Skia Image 包装类，实现 Coil Image 接口
 */


private class SkiaImageWrapper(private val skiaImage: SkiaImage) : Image {
    override val size: Long = (skiaImage.width * skiaImage.height * 4).toLong()
    override val width: Int = skiaImage.width
    override val height: Int = skiaImage.height
    override val shareable: Boolean = true

    override fun draw(canvas: Canvas) {
        canvas.drawImage(skiaImage, 0f, 0f)
    }
}

/**
 * OHOS 图片解码器
 *
 * 使用 OHOS Native Image Framework API 解码图片
 */
class OhosImageDecoder(
    private val source: ImageSource,
    private val options: Options
) : Decoder {

    @OptIn(ExperimentalForeignApi::class)
    override suspend fun decode(): DecodeResult = withContext(Dispatchers.IO) {
        var handle: Long = 0
        try {
            val bytes = source.source().use { buffered -> buffered.readByteArray() }
            println("OHOS Decoder: 缓冲区长度=${bytes.size}")

            handle = bytes.usePinned { pinned ->
                val rawPtr = pinned.addressOf(0)
                println("OHOS Decoder: 调用 create_heif_image ptr=$rawPtr length=${bytes.size}")
                create_heif_image(
                    rawPtr.reinterpret(),
                    bytes.size.toULong(),
                    0f,
                    0f
                )
            }
            if (handle == 0L) {
                throw IllegalStateException("创建 PixelMap 失败")
            }

            // 步骤2：读取像素数据
            memScoped {
                val dataPtr = alloc<CPointerVar<UByteVar>>()
                val widthVar = alloc<UIntVar>()
                val heightVar = alloc<UIntVar>()

                val result = load_image_pixels(handle, dataPtr.ptr, widthVar.ptr, heightVar.ptr)
                if (result != 0) {
                    throw IllegalStateException("读取像素数据失败，错误码: $result")
                }

                val data = dataPtr.value ?: throw IllegalStateException("像素数据为空")
                val width = widthVar.value.toInt()
                val height = heightVar.value.toInt()
                val size = width * height * 4  // RGBA 格式

                // 复制像素数据到 ByteArray
                val byteArray = ByteArray(size)
                for (i in 0 until size) {
                    byteArray[i] = data[i].toByte()
                }

                // 释放 C 侧内存
                free_image_data(data)
                destroy_heif_image(handle)
                handle = 0

                // 使用 Skia 创建 ImageBitmap
                val imageInfo = org.jetbrains.skia.ImageInfo(
                    width,
                    height,
                    org.jetbrains.skia.ColorType.RGBA_8888,
                    org.jetbrains.skia.ColorAlphaType.PREMUL
                )
                val skiaImage = SkiaImage.makeRaster(
                    imageInfo = imageInfo,
                    bytes = byteArray,
                    rowBytes = width * 4
                )

//                val imageBitmap = skiaImage.toComposeImageBitmap()
                println("OHOS Decoder: 解码成功 - ${width}x${height}")

                DecodeResult(
                    image = SkiaImageWrapper(skiaImage),
                    isSampled = false
                )
            }
        } catch (e: Exception) {
            if (handle != 0L) {
                destroy_heif_image(handle)
            }
            println("OHOS Decoder: 解码失败 - ${e.message}")
            e.printStackTrace()
            throw e
        }
    }

    class Factory : Decoder.Factory {
        override fun create(
            result: SourceFetchResult,
            options: Options,
            imageLoader: ImageLoader
        ): Decoder {
            println("[OhosImageDecoder.Factory] create with source=${result.source} options=$options")
            return OhosImageDecoder(result.source, options)
        }
    }
}

@Composable
actual  fun UniversalAsyncImage(
    url: String,
    contentDescription: String?,
    modifier: Modifier,
    onLoading: (() -> Unit)?,
    onSuccess: (() -> Unit)?,
    onError: ((Throwable?) -> Unit)?
) {
    println("[UniversalAsyncImage] enter url=$url contentDescription=$contentDescription modifier=$modifier")
    val context = LocalPlatformContext.current
    println("[UniversalAsyncImage] PlatformContext acquired: $context (${context::class.simpleName})")

    // 创建 ImageLoader，使用 OHOS 自定义解码器
    val imageLoader = remember {
        println("[UniversalAsyncImage] building ImageLoader")
        ImageLoader.Builder(context)
            .components {
                // 添加 OHOS 图片解码器
                add(OhosImageDecoder.Factory())
            }
            .build()
    }
    println("[UniversalAsyncImage] imageLoader=$imageLoader")

    // 使用 Coil 的 AsyncImage
    AsyncImage(
        model = url,
        imageLoader = imageLoader,
        contentDescription = contentDescription,
        modifier = modifier,
        onLoading = {
            onLoading?.invoke()
            println("OHOS AsyncImage: 加载中 - $url")
        },
        onError = { error ->
            val exception = (error as? ErrorResult)?.throwable
            onError?.invoke(exception)
            println("OHOS AsyncImage: 加载失败 - $url, ${exception?.message}")
        },
        onSuccess = {
            onSuccess?.invoke()
            println("OHOS AsyncImage: 加载成功 - $url")
        }
    )
    println("[UniversalAsyncImage] exit")
}
